#include "usart_comm.h"
#include "stm32f1xx_hal.h"

#define PACKET_HEADER 0xAA
#define PACKET_SIZE sizeof(UsartComm_DataAvailable)

// 静态全局变量
static UART_HandleTypeDef *usart_comm_huart;
static volatile UsartComm_Packet_t rx_packet;
static volatile uint8_t packet_received = 0;
static uint8_t rx_buffer[PACKET_SIZE];
static uint8_t rx_index = 0;

// 初始化函数
void UsartComm_Init(UART_HandleTypeDef *huart) {
    usart_comm_huart = huart;
    // 启动接收中断
    HAL_UART_Receive_IT(usart_comm_huart, &rx_buffer[rx_index], 1);
}

// 发送数据包
static void send_packet(UsartComm_Packet_t *packet) {
    // 计算校验和
    packet->checksum = packet->header + packet->cmd;
    for(int i = 0; i < 6; i++) {
        packet->checksum += packet->data[i];
    }
    
    // 使用HAL库发送
    HAL_UART_Transmit(usart_comm_huart, (uint8_t*)packet, PACKET_SIZE, HAL_MAX_DELAY);
}

// 公共发送接口
void BoardComm_SendData(uint8_t cmd, const uint8_t* data, uint8_t length) {
    UsartComm_Packet_t packet = {
        .header = PACKET_HEADER,
        .cmd = cmd
    };
    
    memset(packet.data, 0, 6);
    if(length > 6) length = 6;
    memcpy(packet.data, data, length);
    
    send_packet(&packet);
}

// 接收完成回调(在main.c中调用)
void UsartComm_RxCpltCallback(UART_HandleTypeDef *huart) {
    if(huart == usart_comm_huart) {
        if(rx_index == 0 && rx_buffer[0] == PACKET_HEADER) {
            rx_index++;
        } else if(rx_index > 0 && rx_index < PACKET_SIZE) {
            rx_index++;
        } else {
            rx_index = 0;
        }
        
        // 完整包接收
        if(rx_index == PACKET_SIZE) {
            memcpy((void*)&rx_packet, rx_buffer, PACKET_SIZE);
            
            // 校验
            uint8_t checksum = rx_packet.header + rx_packet.cmd;
            for(int i = 0; i < 6; i++) {
                checksum += rx_packet.data[i];
            }
            
            if(checksum == rx_packet.checksum) {
                packet_received = 1;
            }
            rx_index = 0;
        }
        
        // 重新启动接收
        HAL_UART_Receive_IT(usart_comm_huart, &rx_buffer[rx_index], 1);
    }
}

// 数据可用检查
uint8_t UsartComm_DataAvailable(void) {
    return packet_received;
}

// 获取接收数据
void UsartComm_GetData(uint8_t* cmd, uint8_t* data, uint8_t* length) {
    if(packet_received) {
        *cmd = rx_packet.cmd;
        *length = 6;
        memcpy(data, rx_packet.data, 6);
        packet_received = 0;
    }
}